package com.dz.lm.web.controller.login;

import com.alibaba.fastjson.JSONObject;
import com.dz.lm.common.exception.ServiceException;
import com.dz.lm.common.util.StringUtil;
import com.dz.lm.common.util.WxMini;
import com.dz.lm.common.utils.json.JsonUtils;
import com.dz.lm.common.utils.security.RSAUtil;
import com.dz.lm.common.utils.security.TokenProccess;
import com.dz.lm.dao.userinvite.read.UserInviteDao;
import com.dz.lm.domain.user.SmsInfo;
import com.dz.lm.domain.user.User;
import com.dz.lm.domain.userinvite.UserInvite;
import com.dz.lm.service.account.AccountService;
import com.dz.lm.service.appLogin.AppLoginService;
import com.dz.lm.service.log.LoginLogService;
import com.dz.lm.web.controller.BasicControl;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * 登录
 * 
 * @author zhanghairong
 */
@Controller
@RequestMapping("/rewriteUrl/login")
public class AppLoginControl extends BasicControl{
	
	public Logger logger = LogManager.getLogger(AppLoginControl.class);


	@Resource(name = "readUserInviteDao")
	private UserInviteDao readUserInviteDao;
	@Autowired
    private AppLoginService appLoginService;
	
	@Autowired
    private LoginLogService loginLogService;
	
	@Autowired
    private AccountService accountService;
    
    /**
     * app登录验证
     * 
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/validateLogin")
    public Map<String, Object> validationLogin(HttpServletRequest request) throws ServiceException {
    	System.out.println("App login is starting!");
    	String reqData = request.getAttribute("reqData") != null ? request.getAttribute("reqData").toString() : "";
    	JSONObject _reqData = JSONObject.parseObject(reqData);
    	JSONObject subjo = null;
    	//参数校验
		Vector<String> inparam = new Vector<String>();
		inparam.add("mobilePhone");
		inparam.add("password");
//		inparam.add("pushToken");
		for (String in : inparam) {
			if (!_reqData.containsKey(in)) {
				subjo = new JSONObject();
		    	subjo.put("result", "01");
		    	subjo.put("message", "参数" + in + "异常");
		    	return parameterEncrypt(request, subjo);
			}
		}
		Map<String, Object> param = JsonUtils.readValue(_reqData.toString());
		String mobilePhone = param.get("mobilePhone").toString();
		String password = param.get("password").toString();
		String pushToken = param.get("pushToken") != null? param.get("pushToken").toString() : "";
		Map<String, Object> qryParam = new HashMap<String, Object>();
		qryParam.put("mobilePhone", mobilePhone);
		qryParam.put("password", password);
		qryParam.put("pushToken", pushToken);
		Map<String, Object> user = appLoginService.qryUserInfo(qryParam);
		if (user == null || user.isEmpty() ) {
			subjo = new JSONObject();
	    	subjo.put("result", "03");
	    	subjo.put("message", "您的账户不存在，请确认账户是否正确！");
	    	return parameterEncrypt(request, subjo);
		} else if (!password.equals(user.get("passWord"))) {
			subjo = new JSONObject();
	    	subjo.put("result", "02");
	    	subjo.put("message", "您的账户或密码不正确，请重新输入！");
	    	return parameterEncrypt(request, subjo);
		} else {
			Object userId = user.get("userId");
			param.put("userId", userId);
			qryParam.put("userId", userId);
			//记录登录日志
			loginLogService.addLoginLog(param);
			String token = TokenProccess.getToken();
			param.put("token", token);
			Map<String, Object> tokenMap = appLoginService.qryRyToken(param);
			Object ryToken = "";
			if (tokenMap != null && !tokenMap.isEmpty()) {
				ryToken = tokenMap.get("ryToken");
			}
			Map<String, Object> retData = appLoginService.qryFavoriteMoneyBarList(param);
			subjo = new JSONObject();
			subjo.put("isOn", retData.get("isOn"));
			subjo.put("userInfo", user);
			subjo.put("accessToken", token);
			subjo.put("ryToken", ryToken);
			subjo.put("barList", retData.get("barList"));
			subjo.put("appVerInfo", retData.get("appVerInfo"));
	    	subjo.put("result", "00");
	    	subjo.put("message", "登录成功！");
	    	//保存token信息
	    	loginLogService.addAccessToken(param);
	    	//创建账户信息
	    	accountService.addAccount(param);
		}
		return parameterEncrypt(request, subjo);
    }

    /**
     * app发送短信验证码
     * 
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/sendsms")
    public Map<String, Object> sendsms(HttpServletRequest request) throws ServiceException{
    	String reqData = request.getAttribute("reqData") != null ? request.getAttribute("reqData").toString() : "";
    	JSONObject _reqData = JSONObject.parseObject(reqData);
		JSONObject subjo = new JSONObject();
    	//参数校验
		Vector<String> inparam = new Vector<String>();
		inparam.add("mobilePhone");
		inparam.add("type");
		for (String in : inparam) {
			if (!_reqData.containsKey(in)) {
				subjo = new JSONObject();
		    	subjo.put("result", "01");
		    	subjo.put("message", "参数" + in + "异常");
		    	return parameterEncrypt(request, subjo);
			}
		}
		Map<String, Object> param = JsonUtils.readValue(_reqData.toString());
		String mobilePhone = param.get("mobilePhone").toString();
		String type = param.get("type").toString();
		//校验该账户是否已注册
		Integer cnt = appLoginService.selectByMobilePhoneCnt(mobilePhone);
		if ("1".equals(type)) {
			if(cnt > 0) {
				subjo = new JSONObject();
		    	subjo.put("result", "02");
		    	subjo.put("message", "您已注册过该应用，若忘记密码请返回首页找回密码，否则可直接登录");
		    	return parameterEncrypt(request, subjo);
			}
		} else {
			if(cnt <= 0) {
				subjo = new JSONObject();
		    	subjo.put("result", "03");
		    	subjo.put("message", "您还不是该应用成员，请确认输入的账号是否正确?");
		    	return parameterEncrypt(request, subjo);
			}
		}
		String sendRes = appLoginService.sendSms(mobilePhone);
		subjo = new JSONObject();
		if ("0".equals(sendRes)) {
	    	subjo.put("result", "00");
	    	subjo.put("message", "发送成功，请注意查收");
		} else if("LM1001".equals(sendRes)){
	    	subjo.put("result", "01");
	    	subjo.put("message", "您的短信发送频率过高，请稍后再试");
		} else if("LM1002".equals(sendRes)){
	    	subjo.put("result", "01");
	    	subjo.put("message", "很抱歉，发送短信验证码次数超限，请您明日再试");
		} else {
	    	subjo.put("result", "01");
	    	subjo.put("message", "发送失败");
		}
    	return parameterEncrypt(request, subjo);
    }
    
    /**
     * app注册接口
     * 
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/signUp")
    public Map<String, Object> signUp(HttpServletRequest request) throws ServiceException {
    	String reqData = request.getAttribute("reqData") != null ? request.getAttribute("reqData").toString() : "";
		JSONObject _reqData = JSONObject.parseObject(reqData);
		JSONObject subjo = new JSONObject();
		logger.info("_reqData=" + _reqData);
		//参数校验
		Vector<String> inparam = new Vector<String>();
		inparam.add("mobilePhone");
		inparam.add("verifyCode");
		inparam.add("password");
		inparam.add("confirmPassword");
		for (String in:inparam) {
			if (!_reqData.containsKey(in)) {
				subjo = new JSONObject();
		    	subjo.put("result", "01");
		    	subjo.put("message", "参数" + in + "异常");
		    	return parameterEncrypt(request, subjo);
			}
		}
		Map<String, Object> param = JsonUtils.readValue(_reqData.toString());
		String mobilePhone = param.get("mobilePhone").toString();
		String verifyCode = param.get("verifyCode").toString();
		String password = param.get("password").toString();
		String confirmPassword = param.get("confirmPassword").toString();
		//密码与确认密码进行比较
		if (password != null && !password.equals(confirmPassword)) {
			subjo = new JSONObject();
	    	subjo.put("result", "02");
	    	subjo.put("message", "密码与确认密码不一致，请重新输入！");
	    	return parameterEncrypt(request, subjo);
		}
		//校验短信验证码
		boolean checkFlag = false;
		//查询数据库，查到该手机号码最新的未过期的且未被验证的短信验证码与参数短信验证码进行匹配
		SmsInfo si = appLoginService.qrySmsInfo(mobilePhone);
		if (si!= null){ 
			if (verifyCode.equals(si.getCode())) {
				checkFlag = true;
				//验证通过后更新该条记录的验证状态和验证时间
				appLoginService.updateSmsInfo(si);
			}
		}
		if (!checkFlag) {
			subjo = new JSONObject();
	    	subjo.put("result", "01");
	    	subjo.put("message", "短信验证码错误，请重新输入");
	    	return parameterEncrypt(request, subjo);
		}
		//校验该账户是否已注册
		Integer cnt = appLoginService.selectByMobilePhoneCnt(mobilePhone);
		if(cnt > 0) {
			subjo = new JSONObject();
	    	subjo.put("result", "03");
	    	subjo.put("message", "您已是找钱吧成员啦~是否直接登录?");
	    	return parameterEncrypt(request, subjo);
		}
		//保存注册数据
		if (param.get("pwdLevel") == null || "".equals(param.get("pwdLevel").toString())) {
			param.put("pwdLevel","02");
		}
		cnt = appLoginService.addNewUserInfo(param);
		//返回注册结果
		if (cnt > 0) {
			subjo = new JSONObject();
	    	subjo.put("result", "00");
	    	subjo.put("message", "注册成功");
	    	return parameterEncrypt(request, subjo);
		} else {
			subjo = new JSONObject();
	    	subjo.put("result", "04");
	    	subjo.put("message", "数据保存异常，注册失败");
	    	return parameterEncrypt(request, subjo);
		}
    }
	/**
	 * 微信登录
	 * @param request
	 * @return
	 * @throws ServiceException
	 */
	@ResponseBody
	@RequestMapping("/wxLogin")
	public Map wxLogin(HttpServletRequest request) throws ServiceException {
		String result = "01";
		String message="";
		Object data=null;
		JSONObject subjo = new JSONObject();
		String reqData = request.getAttribute("_reqData") != null ? request.getAttribute("_reqData").toString() : "";
		Map<String, Object> param = JsonUtils.readValue(reqData.toString());
		//登录人
		String code = param.get("code") != null ? param.get("code").toString() : "";
		String encryptedData = param.get("encryptedData") != null ? param.get("encryptedData").toString() : "";
		String iv = param.get("iv") != null ? param.get("iv").toString() : "";
		try {
            result= "00";
			Map wxInfo = WxMini.getWxInfo(code, encryptedData, iv);
			String oppenid = StringUtil.getString(wxInfo.get("openid"));
			String phone = StringUtil.getString(wxInfo.get("phone"));
			Map<String, Object> user = appLoginService.qryUserInfo(wxInfo);
			if(user != null){
				Object userId = user.get("userId");
				param.put("userId", userId);
				//记录登录日志
				loginLogService.addLoginLog(param);
				String token = TokenProccess.getToken();
				param.put("token", token);
				Map<String, Object> tokenMap = appLoginService.qryRyToken(param);
				Object ryToken = "";
				if (tokenMap != null && !tokenMap.isEmpty()) {
					ryToken = tokenMap.get("ryToken");
				}
				Map<String, Object> retData = appLoginService.qryFavoriteMoneyBarList(param);
				UserInvite userInvite = readUserInviteDao.selectByUserId(Integer.valueOf(userId.toString()));
				if(userInvite != null){
					subjo.put("subCode",userInvite.getCode() );
				}
				subjo.put("isOn", retData.get("isOn"));
				subjo.put("userInfo", user);
				subjo.put("accessToken", token);
				subjo.put("ryToken", ryToken);
				subjo.put("barList", retData.get("barList"));
				subjo.put("appVerInfo", retData.get("appVerInfo"));
				subjo.put("result", "00");
				subjo.put("message", "登录成功！");
				//保存token信息
				loginLogService.addAccessToken(param);
				//创建账户信息
				accountService.addAccount(param);
				loginLogService.addLoginLog(param);

			}else {

				wxInfo.put("mobilePhone",phone);
				user = appLoginService.qryUserInfo(wxInfo);
				if(user != null){
					user.put("oppenid",oppenid);
					appLoginService.updateUserInfo(user);
					Object userId = user.get("userId");
					param.put("userId", userId);
					//记录登录日志
					loginLogService.addLoginLog(param);
					String token = TokenProccess.getToken();
					param.put("token", token);
					Map<String, Object> tokenMap = appLoginService.qryRyToken(param);
					Object ryToken = "";
					if (tokenMap != null && !tokenMap.isEmpty()) {
						ryToken = tokenMap.get("ryToken");
					}
					Map<String, Object> retData = appLoginService.qryFavoriteMoneyBarList(param);
					subjo = new JSONObject();
					UserInvite userInvite = readUserInviteDao.selectByUserId(Integer.valueOf(userId.toString()));
					if(userInvite != null){
						subjo.put("subCode",userInvite.getCode() );
					}
					subjo.put("isOn", retData.get("isOn"));
					subjo.put("userInfo", user);
					subjo.put("accessToken", token);
					subjo.put("ryToken", ryToken);
					subjo.put("barList", retData.get("barList"));
					subjo.put("appVerInfo", retData.get("appVerInfo"));
					subjo.put("result", "00");
					subjo.put("message", "登录成功！");
					//保存token信息
					loginLogService.addAccessToken(param);
					//创建账户信息
					accountService.addAccount(param);
					loginLogService.addLoginLog(param);

				}else {
					param.clear();
					param.put("mobilePhone",phone);
					param.put("oppenId",oppenid);
                    param.put("platform","Wx");
					param.put("password","202cb962ac59075b964b07152d234b70");
					int cnt = appLoginService.addNewUserInfo(param);
					if(cnt > 0){
						param.put("userId", cnt);
						//记录登录日志
						loginLogService.addLoginLog(param);
						String token = TokenProccess.getToken();
						param.put("token", token);
						Map<String, Object> tokenMap = appLoginService.qryRyToken(param);
						Object ryToken = "";
						if (tokenMap != null && !tokenMap.isEmpty()) {
							ryToken = tokenMap.get("ryToken");
						}
						wxInfo.clear();
						wxInfo.put("userId",cnt);
						Map map = appLoginService.qryUserInfo(wxInfo);

						Map<String, Object> retData = appLoginService.qryFavoriteMoneyBarList(param);

						UserInvite userInvite = readUserInviteDao.selectByUserId(cnt);
						subjo = new JSONObject();
						if(userInvite != null){
							subjo.put("subCode",userInvite.getCode() );
						}
						subjo.put("isOn", retData.get("isOn"));
						subjo.put("userInfo", map);
						subjo.put("accessToken", token);
						subjo.put("ryToken", ryToken);
						subjo.put("barList", retData.get("barList"));
						subjo.put("appVerInfo", retData.get("appVerInfo"));
						subjo.put("result", "00");
						subjo.put("message", "登录成功！");
						//保存token信息
						loginLogService.addAccessToken(param);
						//创建账户信息
						accountService.addAccount(param);
					}
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
            result ="01";
			 message="获取失败";
		}
		if(param.get("platform").equals("Android")){
			Map<String, Object> retData = new HashMap();
			retData.put("message", message);
			retData.put("result",result);
			retData.put("data",data);
			subjo.putAll(retData);
			return parameterEncrypt(request, subjo);
		}else {
			subjo.put("message", message);
			subjo.put("result", result);
			subjo.put("data",data);
			return  subjo;
		}
	}
    /**
     * app找回密码
     * 
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/findPassword")
    public Map<String, Object> findPassword(HttpServletRequest request) throws ServiceException {
    	String reqData = request.getAttribute("reqData") != null ? request.getAttribute("reqData").toString() : "";
		JSONObject _reqData = JSONObject.parseObject(reqData);
		JSONObject subjo = new JSONObject();
		logger.info("_reqData=" + _reqData);
		//参数校验
		Vector<String> inparam = new Vector<String>();
		inparam.add("mobilePhone");
		inparam.add("verifyCode");
		inparam.add("password");
		inparam.add("confirmPassword");
		for (String in:inparam) {
			if (!_reqData.containsKey(in)) {
				subjo = new JSONObject();
		    	subjo.put("result", "01");
		    	subjo.put("message", "参数" + in + "异常");
		    	return parameterEncrypt(request, subjo);
			}
		}
		Map<String, Object> param = JsonUtils.readValue(_reqData.toString());
		String mobilePhone = param.get("mobilePhone").toString();
		String verifyCode = param.get("verifyCode").toString();
		String password = param.get("password").toString();
		String confirmPassword = param.get("confirmPassword").toString();

		//密码与确认密码进行比较
		if (password != null && !password.equals(confirmPassword)) {
			subjo = new JSONObject();
	    	subjo.put("result", "02");
	    	subjo.put("message", "密码与确认密码不一致，请重新输入！");
	    	return parameterEncrypt(request, subjo);
		}
		
		//校验该账户是否已注册
		Integer cnt = appLoginService.selectByMobilePhoneCnt(mobilePhone);
		if(cnt <= 0) {
			//未注册
			subjo = new JSONObject();
	    	subjo.put("result", "02");
	    	subjo.put("message", "您还不是找钱吧成员，请确认输入的账号是否正确?");
	    	return parameterEncrypt(request, subjo);
		}
		
		//校验短信验证码
		boolean checkFlag = false;
		//查询数据库，查到该手机号码最新的未过期的且未被验证的短信验证码与参数短信验证码进行匹配
		SmsInfo si = appLoginService.qrySmsInfo(mobilePhone);
		if (si!= null){ 
			if (verifyCode.equals(si.getCode())) {
				checkFlag = true;
				//验证通过后更新该条记录的验证状态和验证时间
				appLoginService.updateSmsInfo(si);
			}
		}
		if (!checkFlag) {
			subjo = new JSONObject();
	    	subjo.put("result", "01");
	    	subjo.put("message", "短信验证码错误，请重新输入");
	    	return parameterEncrypt(request, subjo);
		}

		//更新用户数据
		if (param.get("pwdLevel") == null || "".equals(param.get("pwdLevel").toString())) {
			param.put("pwdLevel","02");
		}
		cnt = appLoginService.updateUserInfo(param);
		//返回更新结果
		if (cnt > 0) {
			subjo = new JSONObject();
	    	subjo.put("result", "00");
	    	subjo.put("message", "找回密码成功");
	    	return parameterEncrypt(request, subjo);
		} else {
			subjo = new JSONObject();
	    	subjo.put("result", "04");
	    	subjo.put("message", "数据保存异常，找回密码失败");
	    	return parameterEncrypt(request, subjo);
		}
    }
    /**
     * 获取融云Token
     * 
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/getRyToken")
    public Map<String, Object> getRyToken(HttpServletRequest request) {
    	try{
    		String userId = request.getAttribute("userId").toString();
    		String ryToken = appLoginService.getRyToken(userId);
    		JSONObject subjo = new JSONObject();
    		if (ryToken != null && !"".equals(ryToken)) {
    	    	subjo.put("result", "00");
    	    	subjo.put("message", "获取融云Token成功");
    	    	subjo.put("ryToken", ryToken);
    		} else {
    	    	subjo.put("result", "01");
    	    	subjo.put("message", "获取融云Token失败");
    		}
	    	return parameterEncrypt(request, subjo);
    	} catch(ServiceException e){
    		JSONObject subjo = new JSONObject();
	    	subjo.put("result", "01");
	    	subjo.put("message", "获取融云Token失败");
	    	return parameterEncrypt(request, subjo);
    	}
    }
    
    public static void testData(){
    	String des3Key = "abcdefgh12345678";
    	String _reqKey = RSAUtil.encryptByRSAPub(RSAPUBLICKEY, des3Key);
    	JSONObject jo = new JSONObject();
    	
    	jo.put("mobilePhone", "18600880808");
    	jo.put("verifyCode", "111111");
    	jo.put("password", "aaaa1234");
    	jo.put("confirmPassword", "aaaa1234");
    	jo.put("type", "1");
    	jo.put("size", 10);
    	jo.put("position", 0);
    	
    	String reqData = RSAUtil.encryptBy3Des(des3Key, jo.toString());
    	System.out.println("_reqKey=" + _reqKey);
    	System.out.println("_reqData=" + reqData);
    }
    
    public static void main(String args[]) {
    	testData();
    }
}
